using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using Belmost4PDA.Constants;
using Belmost4PDA.Fasade;
using System;

namespace Belmost4PDA.Logic
{
    public class InterfaceDispatcher
    {
        public static InterfaceDispatcher _instance = null;
        public AbstractState CurrentState = new StateView();
        public AbstractControl TopControls = null;
        public List<AbstractMapper> AllMappers = null;
        public StateRecord RunningState = null;
        public ControlsBuilder builder = new ControlsBuilder();
        public Form workedForm = null;
        public static Stack<int> IDs = new Stack<int>();
        public static int CurrentPanel = -1;
        private HintView Hint=new HintView();
        private static void Init()
        {
            if (_instance == null)
                lock (typeof(InterfaceDispatcher))
                {
                    _instance = new InterfaceDispatcher();
                }
        }


        public virtual void _StartStateInterface(StateRecord stateRecord, Form form)
        {
            _StartStateInterface(stateRecord, form, false);   
        }
        
        public virtual void _StartStateInterface(StateRecord stateRecord, Form form, bool Lite)
        {
            ParamItem item = new ParamItem();
            item.IDParam = -1;
            builder.Build(stateRecord, item,Lite);
            form.Menu = builder.GetMenu();
            TopControls = builder.GetControls();
            AllMappers = builder.GetMappers();
            RunningState = stateRecord;
            workedForm = form;
            if (workedForm.Menu.MenuItems.Count > 1)
            {
                workedForm.Menu.MenuItems[0].Popup += new EventHandler(Hint_Click);
                workedForm.Menu.MenuItems[1].Popup += new EventHandler(Hint_Click);
            }
            CurrentPanel = -1;
            IDs.Clear();
            CurrentState.SetupControls(workedForm);
        }
        
        public static void StartStateInterface(StateRecord stateRecord, Form form)
        {
            StartStateInterface(stateRecord, form, false);    
        }
        /// --- public interface
        /// <summary>
        /// Starts the state interface.
        /// </summary>
        /// <param name="stateRecord">The state record.</param>
        /// <param name="form">The form.</param>
        /// <param name="Lite">Is Lite version</param>
        public static void StartStateInterface(StateRecord stateRecord, Form form, bool Lite)
        {
            Init();
            _instance._StartStateInterface(stateRecord, form, Lite);
            CurrentPanel = -1;
            IDs.Clear();
        }

        /// <summary>
        /// Sets the state.
        /// </summary>
        /// <param name="state">The state.</param>
        public static void SetState(AbstractState state)
        {
            Init();
            ParamItem saveParam = _instance.CurrentState.WorkedParam;
            _instance.CurrentState = state;
            _instance.CurrentState.WorkedParam = saveParam;
        }
        /// <summary>
        /// Execs the command.
        /// </summary>
        /// <param name="Command">The command.</param>
        public static void ExecCommand(AbstractCommand Command)
        {
            Init();
            _instance._ExecCommand(Command);
        }


        /// <summary>
        /// Quits this instance.
        /// </summary>
        public static void Quit()
        {
            Init();
            _instance._Quit();
        }

        public virtual void _ExecCommand(AbstractCommand command)
        {
            command.Execute(ref CurrentState, ref TopControls, ref AllMappers);
            CurrentState.SetupControls(workedForm);
        }

        public virtual void _Quit()
        {
            // clear controls
            _instance.TopControls = ControlsBuilder.Create(ControlType.MainControl, false, false);
            _instance.workedForm.Menu.MenuItems.Clear();
            RunningState.QuitState();
            if (_instance.CurrentState != null)
            {
                _instance.CurrentState = new StateView();
            }
        }


        ///------ static executors for controls


        public static void SetPanel(int panelID)
        {
            Init();
            _instance._SetPanel(panelID);
            CurrentPanel = panelID;
        }

        public const int ControlsXDelta = 5;
        public const int ControlsLeft = 15;
        public virtual void _SetPanel(int panelID)
        {
            int x = 0;
            List<AbstractControl> controls = new List<AbstractControl>();
            TopControls.GetControlsOfPanel(controls, panelID);
            // initialize
            workedForm.Controls.Clear();
            
            if (TopControls.GetGrid() != null)
            {
                ListView lw = (ListView)TopControls.GetGrid().GetFormControl();
                lw.Width = workedForm.Width - 2 * ControlsLeft;
                lw.Left = ControlsLeft;
                lw.Top = ControlsXDelta;
                lw.Height = 100;
                x += 100 + ControlsXDelta;
                workedForm.Controls.Add(lw);
                lw.Parent = workedForm;
            }
            // copy controls
            Hint.BackColor = Color.LightGoldenrodYellow; 
            Hint.Width = workedForm.Width - 2 * ControlsLeft;
            Hint.Left = ControlsLeft;
            Hint.Height = 1;
            Hint.Top = x;
            Hint.Click+=new EventHandler(Hint_Click);
            workedForm.Controls.Add(Hint);
            foreach (AbstractControl control in controls)
            {
                if (control.GetCaption() != "")
                {
                    Label label = new Label();
                    label.Text = control.GetCaption();
                    SetupControlPos(label, ref x);
                }
                SetupControlPos(control.GetFormControl(), ref x);
            }
            CurrentState.SetupControls(workedForm);
        }

        private void SetupControlPos(Control control, ref int x)
        {
            control.Left = ControlsLeft;
            control.Width = workedForm.Width - 2 * ControlsLeft;
            x += ControlsXDelta;
            control.Top = x;
            x += control.Height;
            HintCombo check = control as HintCombo;
            if (check != null) check.SelectedValueChanged += new EventHandler(hintCombo_SelectedValueChanged);
            control.GotFocus+=new EventHandler(control_GotFocus);
            workedForm.Controls.Add(control);
            control.Parent = workedForm;
        }
        private void control_GotFocus(object sender, EventArgs e)
        {
            Hint.SetLocation(((Control) sender).Location.Y);
            Hint.SetHint(((Control) sender).Text);
          
        }
        private void hintCombo_SelectedValueChanged(object sender, EventArgs e)
        {
            if (((Control)sender).Focused)
            {
                Hint.SetLocation(((Control) sender).Location.Y);
                Hint.SetHint(((ComboBox) sender).SelectedItem.ToString());
            }
        }
        private void Hint_Click(object sender, EventArgs e)
        {
            Hint.Visible = false;

        }

    }
}